/*
 PureMVC - Copyright(c) 2006-08 Futurescale, Inc., Some rights reserved.
 Your reuse is governed by the Creative Commons Attribution 3.0 United States License
*/
package org.puremvc.as3.core
{
	import org.puremvc.as3.core.*;
	import org.puremvc.as3.interfaces.*;
	import org.puremvc.as3.patterns.observer.*;
	public class Controller implements IController
	{
		public function Controller( )
		{
			if (instance != null) throw Error(SINGLETON_MSG);
			instance = this;
			commandMap = new Object();
			commands = new Object();
			initializeController();	
		}
		/**
		 * 初始化，获取View的引用
		 */
		protected function initializeController(  ) : void 
		{
			view = View.getInstance();
		}
	
		public static function getInstance() : IController
		{
			if ( instance == null ) instance = new Controller( );
			return instance;
		}
		/**
		 * 收到notification通知被执行；
		 * 动态创建Command对象，执行实现接口ICommand的对象的execute方法
		 * @param	note
		 */
		public function executeCommand( note : INotification ) : void
		{
			var commandClassRef : Class = commandMap[ note.getName() ];
			if ( commandClassRef == null ) return;
			var commandInstance : ICommand = commands[note.getName()];
			if (!commandInstance)
			{
				commandInstance = new commandClassRef();
				commands[note.getName()] = commandInstance;
			}
			commandInstance.execute( note );
		}
		/**
		 * 注册Command到Controller中，
		 * 然后注册Observer观察者到View中（如果收到notification通知则会执行回调函数）executeCommand；
		 * 缓存Command类对象到commandMap中。
		 * @param	notificationName 
		 * @param	commandClassRef
		 */
		public function registerCommand( notificationName : String, commandClassRef : Class ) : void
		{
			if ( commandMap[ notificationName ] == null ) {
				view.registerObserver( notificationName, new Observer( executeCommand, this ) );
			}
			commandMap[ notificationName ] = commandClassRef;
		}
		
		public function hasCommand( notificationName:String ) : Boolean
		{
			return commandMap[ notificationName ] != null;
		}

		public function removeCommand( notificationName : String ) : void
		{
			// if the Command is registered...
			if ( hasCommand( notificationName ) )
			{
				// remove the observer
				view.removeObserver( notificationName, this );
							
				// remove the command
				commandMap[ notificationName ] = null;
			}
		}
		
		protected var commands:Object;
		// Local reference to View 
		protected var view : IView;
		
		// Mapping of Notification names to Command Class references
		protected var commandMap : Object;

		// Singleton instance
		protected static var instance : IController;

		// Message Constants
		protected const SINGLETON_MSG : String = "Controller Singleton already constructed!";

	}
}